package org.example.controller;

import org.example.domain.CartItem;
import org.example.service.CartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/cart")
public class CartController {

    @Autowired
    private CartService cartService;
    
    @Autowired
    private StringRedisTemplate redisTemplate;

    @PostMapping("/add")
    public ResponseEntity<?> addToCart(@RequestBody CartItem cartItem) {
        try {
            cartService.addToCart(cartItem);
            Map<String, Object> response = new HashMap<>();
            response.put("code", 200);
            response.put("message", "添加成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("code", 500);
            response.put("message", "添加失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @DeleteMapping("/remove/{userId}/{fruitId}")
    public ResponseEntity<?> removeFromCart(@PathVariable String userId, @PathVariable Long fruitId) {
        try {
            cartService.removeFromCart(userId, fruitId);
            Map<String, Object> response = new HashMap<>();
            response.put("code", 200);
            response.put("message", "删除成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("code", 500);
            response.put("message", "删除失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @PutMapping("/update/{userId}/{fruitId}")
    public ResponseEntity<?> updateQuantity(
            @PathVariable String userId,
            @PathVariable Long fruitId,
            @RequestParam Integer quantity) {
        try {
            cartService.updateQuantity(userId, fruitId, quantity);
            Map<String, Object> response = new HashMap<>();
            response.put("code", 200);
            response.put("message", "更新成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("code", 500);
            response.put("message", "更新失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @GetMapping("/items/{userId}")
    public ResponseEntity<?> getCartItems(@PathVariable String userId) {
        try {
            List<CartItem> items = cartService.getCartItems(userId);
            Map<String, Object> response = new HashMap<>();
            response.put("code", 200);
            response.put("message", "success");
            response.put("data", items);
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("code", 500);
            response.put("message", "获取失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @DeleteMapping("/clear/{userId}")
    public ResponseEntity<?> clearCart(@PathVariable String userId) {
        try {
            cartService.clearCart(Integer.parseInt(userId));
            Map<String, Object> response = new HashMap<>();
            response.put("code", 200);
            response.put("message", "清空成功");
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            Map<String, Object> response = new HashMap<>();
            response.put("code", 500);
            response.put("message", "清空失败: " + e.getMessage());
            return ResponseEntity.ok(response);
        }
    }

    @PostMapping("/checkout")
    public ResponseEntity<?> checkout(@RequestBody Map<String, Object> request) {
        Integer userId = (Integer) request.get("userId");
        List<Map<String, Object>> items = (List<Map<String, Object>>) request.get("items");
        
        // 用户订单锁
        String userLockKey = "lock:order:" + userId;
        // 商品库存锁列表
        List<String> stockLockKeys = items.stream()
            .map(item -> "lock:stock:" + item.get("id"))
            .collect(Collectors.toList());
        
        try {
            // 1. 先获取用户订单锁
            Boolean userLocked = redisTemplate.opsForValue()
                .setIfAbsent(userLockKey, "1", 10, TimeUnit.SECONDS);
                
            if (Boolean.FALSE.equals(userLocked)) {
                HashMap<String, Object> returnMap = new HashMap<>();
                returnMap.put("code",500);
                returnMap.put("message","您有正在处理的订单，请稍后重试");
                return ResponseEntity.ok(returnMap);
            }
            
            // 2. 再获取所有商品的库存锁
            boolean stockLocked = acquireLocks(stockLockKeys);
            if (!stockLocked) {
                HashMap<String, Object> returnMap = new HashMap<>();
                returnMap.put("code",500);
                returnMap.put("message","商品库存正在变动，请稍后重试");
                return ResponseEntity.ok(returnMap);
            }
            
            // 3. 检查库存
            for (Map<String, Object> item : items) {
                Long fruitId = Long.valueOf(item.get("fruitId").toString());
                Long inventoryId=Long.valueOf(item.get("id").toString());
                Integer quantity = Integer.valueOf(item.get("quantity").toString());

                if (!cartService.checkStock(inventoryId, quantity)) {
                    HashMap<String, Object> returnMap = new HashMap<>();
                    returnMap.put("code",500);
                    returnMap.put("message","商品库存不足");
                    return ResponseEntity.ok(returnMap);
                }
            }
            
            // 4. 扣减库存并生成订单
            cartService.checkout(userId, items);
            HashMap<String, Object> returnMap = new HashMap<>();
            returnMap.put("code",200);
            returnMap.put("message","结算成功");
            return ResponseEntity.ok(returnMap);
            
        } catch (Exception e) {
            HashMap<String, Object> returnMap = new HashMap<>();
            returnMap.put("code",500);
            returnMap.put("message","结算失败: " + e.getMessage());
            return ResponseEntity.ok(returnMap);
        } finally {
            // 先释放商品锁，再释放用户锁
            releaseLocks(stockLockKeys);
            redisTemplate.delete(userLockKey);
        }
    }

    private boolean acquireLocks(List<String> keys) {
        return keys.stream().allMatch(key -> 
            Boolean.TRUE.equals(redisTemplate.opsForValue()
                .setIfAbsent(key, "1", 10, TimeUnit.SECONDS))
        );
    }

    private void releaseLocks(List<String> keys) {
        keys.forEach(key -> redisTemplate.delete(key));
    }
} 